/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sismol.data;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;
import sismol.cartography.Linha;
import sismol.cartography.Onibus;
import sismol.cartography.Ponto;
import sismol.cartography.Terminal;
import sismol.cartography.Trecho;
import sismol.cartography.TrechoAtual;

/**
 *
 * @author koji
 */
public class GerenciadorCrud {

    private EntityManager em = Persistence.createEntityManagerFactory("sismolPU").createEntityManager();

    public Linha criarLinhaCompleta(Linha linha, Integer numeroOnibus) {
        Linha novaLinha = new Linha();
        novaLinha.setNome(linha.getNome());

        this.em.getTransaction().begin();
        this.em.persist(novaLinha);
        this.em.getTransaction().commit();

        List<Trecho> trechos = linha.getTrechos();
        List<Trecho> novosTrechos = new ArrayList<Trecho>();
        List<Ponto> pontosSalvos = new ArrayList<Ponto>();
        for (Trecho trecho : trechos) {
            Ponto pontoA = trecho.getPontoA();
            Ponto pontoB = trecho.getPontoB();
            
            if (!pontosSalvos.contains(pontoA)) {
                this.em.getTransaction().begin();
                this.em.persist(pontoA);
                this.em.getTransaction().commit();
                pontosSalvos.add(pontoA);
            } else {
                pontoA = pontosSalvos.get(pontosSalvos.indexOf(pontoA));
            }

            if (!pontosSalvos.contains(pontoB)) {
                this.em.getTransaction().begin();
                this.em.persist(pontoB);
                this.em.getTransaction().commit();
                pontosSalvos.add(pontoB);
            } else {
                pontoB = pontosSalvos.get(pontosSalvos.indexOf(pontoB));
            }

            trecho.setLinha(novaLinha);
            trecho.setPontoA(pontoA);
            trecho.setPontoB(pontoB);

            this.em.getTransaction().begin();
            this.em.persist(trecho);
            this.em.getTransaction().commit();

            novosTrechos.add(trecho);
        }
        novaLinha.setTrechos(novosTrechos);


        for (int i = 0; i < numeroOnibus; i++) {
            Onibus onibus = new Onibus();
            onibus.setLinha(novaLinha);

            this.em.getTransaction().begin();
            this.em.persist(onibus);
            this.em.getTransaction().commit();

            TrechoAtual trechoAtual = new TrechoAtual();
            trechoAtual.setOnibus(onibus);
            trechoAtual.setTrecho(trechos.iterator().next());
            trechoAtual.setHoraUltimoPonto((new Date()).getTime());

            this.em.getTransaction().begin();
            this.em.persist(trechoAtual);
            this.em.getTransaction().commit();

        }

        return novaLinha;
    }

    public Onibus criarOnibusDaLinha(Linha linha) {
        Linha attachedLinha = this.em.find(Linha.class, linha.getId());

        Onibus onibus = new Onibus();
        onibus.setLinha(attachedLinha);

        this.em.getTransaction().begin();
        this.em.persist(onibus);
        this.em.getTransaction().commit();

        TrechoAtual trechoAtual = new TrechoAtual();
        trechoAtual.setOnibus(onibus);
        trechoAtual.setTrecho(attachedLinha.getTrechos().iterator().next());
        trechoAtual.setHoraUltimoPonto((new Date()).getTime());

        this.em.getTransaction().begin();
        this.em.persist(trechoAtual);
        this.em.getTransaction().commit();

        return onibus;
    }

    public Terminal criarHorariosTerminal(Long pontoId, List<Long> horarios) {
        Ponto ponto = this.em.find(Ponto.class, pontoId);

        Query query = this.em.createQuery("SELECT x FROM " + Terminal.class.getSimpleName() + " x WHERE x.terminal = :terminal");
        query.setParameter("terminal", ponto);

        Terminal terminal = null;
        try {
            terminal = (Terminal) query.getSingleResult();
        } catch(NoResultException e) {
        }

        if (terminal == null) {
            terminal = new Terminal();
            terminal.setTerminal(ponto);
            terminal.setSaidas(horarios);

            this.em.getTransaction().begin();
            this.em.persist(terminal);
            this.em.getTransaction().commit();
        } else {
            terminal.setSaidas(horarios);

            this.em.getTransaction().begin();
            this.em.merge(terminal);
            this.em.getTransaction().commit();
        }

        return terminal;
    }
}
